package org.jeecg.modules.system.aspect;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.jeecg.common.constant.enums.SysLogOperateType;
import org.jeecg.common.constant.enums.SysLogType;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.service.ISysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;

/**
 * 系统日志，切面处理类
 *
 * @Author scott
 * @email jeecgos@163.com
 * @Date 2018年1月14日
 */
@Aspect
@Component
public class SqlLogAspect {

	@Autowired
	private ISysBaseAPI sysBaseAPI;

	//@Pointcut("execution(public * org.springframework.jdbc.core.JdbcTemplate.query(..)) || execution(public * org.springframework.jdbc.core.JdbcTemplate.update(..))")
	//@Pointcut("execution(public * org.springframework.jdbc.core.JdbcTemplate.update(..))")
	public void sql() {

	}

	//@After("sql()")
	public void after(JoinPoint joinPoint) throws Throwable {
		Map<String, Object> param =  getFieldsName(joinPoint);
		
		Object sql = param.get("sql");
		if (sql != null) {
			LoginUser loginUser = getLoginUser();
			if (loginUser != null) {
				sysBaseAPI.addLog(String.format("sql:%s", sql), SysLogType.DEBUG, SysLogOperateType.DB_DEBUG, loginUser.getId());
			}
		}
		
	}

	/**
     * 获取参数列表
     *
     * @param joinPoint
     * @return
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     */
    private static Map<String, Object> getFieldsName(JoinPoint joinPoint) {
        // 参数值
        Object[] args = joinPoint.getArgs();
        ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String[] parameterNames = pnd.getParameterNames(method);
        Map<String, Object> paramMap = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            paramMap.put(parameterNames[i], args[i]);
        }
        return paramMap;
    }
    
  	private LoginUser getLoginUser() {
  		LoginUser sysUser = null;
  		try {
  			sysUser = SecurityUtils.getSubject().getPrincipal() != null ? (LoginUser) SecurityUtils.getSubject().getPrincipal() : null;
  		} catch (Exception e) {
  			sysUser = null;
  		}
  		return sysUser;
  	}
	
}
